﻿using System;
using System.Management;
using System.ServiceProcess;
using System.Threading;
using TipokHostManager.Model;
using TipokHostManager.WMIManager;

namespace TipokHostManager
{
    public class MonitorLocalService
    {
        public event EventHandler<NoftifyAdminEventArgs> ServerStartEvent;
        public event EventHandler<NoftifyAdminEventArgs> ServerStopEvent;
        public event EventHandler<NoftifyAdminEventArgs> ServerInstallEvent;
        public event EventHandler<NoftifyAdminEventArgs> ServerUnInstallEvent;
        public event EventHandler<NoftifyAdminEventArgs> ServerOhterThingEvent;

        private ManagementEventWatcher watcher = new ManagementEventWatcher();
        private Thread thread;
        public void Start()
        {
            thread = new Thread(new ThreadStart(init));
            thread.IsBackground = true;
            thread.Start();
        }

        public void Stop()
        {
            watcher.Stop();
            watcher.Dispose();
            watcher = null;
            thread.Abort();
            thread = null;
        }

        void init()
        {
            WqlEventQuery query = new WqlEventQuery(
             EnumWMIEventClassName.__InstanceOperationEvent.ToString(),
             new TimeSpan(0, 0, 1),
             "TargetInstance isa \"" + EnumWMICalassName.Win32_Service.ToString() + "\" " + GlobalHelper.MonitorLocalServiceWql
            );
            //System.Collections.Specialized.StringCollection collection =
            //   new System.Collections.Specialized.StringCollection();
            //collection.Add("TargetInstance.Name");
            //query.GroupByPropertyList = collection;
            //query.HavingCondition = "NumberOfEvents >2";
            watcher.Query = query;
            Console.WriteLine("application trigger event monitor service is open.");
            // times out watcher.WaitForNextEvent in 5 seconds
            //watcher.Options.Timeout = new TimeSpan(0,0,10);
            watcher.Start();
            while (true)
            {
                ManagementBaseObject e = watcher.WaitForNextEvent();
                EnumWMIEventClassName classValue = EnumWMIEventClassName.__InstanceOperationEvent;
                switch (e.SystemProperties["__Class"].Value.ToString())
                {
                    case "__InstanceCreationEvent":
                        classValue = EnumWMIEventClassName.__InstanceCreationEvent;
                        break;
                    case "__InstanceDeletionEvent":
                        classValue = EnumWMIEventClassName.__InstanceDeletionEvent;
                        break;
                    case "__InstanceModificationEvent":
                        classValue = EnumWMIEventClassName.__InstanceModificationEvent;
                        break;
                    case "__InstanceOperationEvent":
                        classValue = EnumWMIEventClassName.__InstanceOperationEvent;
                        break;
                }
                string serviceName = ((ManagementBaseObject)e["TargetInstance"])["Name"].ToString();
                var service = ServiceManager.Instance.GetService(serviceName);
                NoftifyAdminEventArgs nAEA = new NoftifyAdminEventArgs();
                nAEA.Model = service;
                nAEA.Host = ServiceManager.Instance.Host;
                NotifyEvent(classValue, service, nAEA, e);  
            }
        }

        void NotifyEvent(EnumWMIEventClassName classValue,TipokHostContract.ServiceModel service,
            NoftifyAdminEventArgs nAEA,ManagementBaseObject e)
        {
            if (classValue == EnumWMIEventClassName.__InstanceModificationEvent)
            {//启动或关闭服务,启动会出发2次，1次是启动中，另外一次是runing 

                if ((service.State == ServiceControllerStatus.Stopped || service.State == ServiceControllerStatus.StopPending)
                    && ServerStopEvent != null)
                {
                    ServerStopEvent(e, nAEA);
                }
                else if ((service.State == ServiceControllerStatus.StartPending || service.State == ServiceControllerStatus.Running)
                    && ServerStartEvent != null)
                {
                    ServerStartEvent(e, nAEA);
                }
                else if (ServerOhterThingEvent != null)
                {
                    ServerOhterThingEvent(e, nAEA);
                }
            }
            else
            {
                //install or uninstall service   
                if (classValue == EnumWMIEventClassName.__InstanceCreationEvent
                    && ServerInstallEvent != null)
                {
                    ServerInstallEvent(e, nAEA);
                }
                else if (classValue == EnumWMIEventClassName.__InstanceDeletionEvent
                    && ServerUnInstallEvent != null)
                {
                    ServerUnInstallEvent(e, nAEA);
                }
                else if (ServerOhterThingEvent != null)
                {
                    ServerOhterThingEvent(e, nAEA);
                }
            }
        }
    }
}
